#include "StdAfx.h"
#include "HeaderReader.h"

#include "Header.h"
#include "File.h"

#include <cassert>

	namespace las
	{
		HeaderReader::HeaderReader( File *pFile )
		{
			m_pFile = pFile;
			m_pHeader = new Header;
		}

		HeaderReader::~HeaderReader()
		{

		}

		void HeaderReader::ReadHeader()
		{
			uint8_t n1 = 0;
			uint16_t n2 = 0;
			uint32_t n4 = 0;
			uint64_t n8 = 0;
			double x1 = 0;
			double y1 = 0;
			double z1 = 0;
			double x2 = 0;
			double y2 = 0;
			double z2 = 0;
			char fsig[4];
			char buf[32];


			m_pFile->Seek(0, File::eBegin);

			m_pFile->Read(fsig, 4);
			m_pHeader->SetFileSignature(std::string(fsig,4));
			m_pFile->Read(&n2, 2);
			m_pHeader->SetSourceID(n2);
			m_pFile->Read(&n2, 2);
			m_pHeader->SetGlobalEncoding(n2);

			GUID guid;
			m_pFile->Read(&guid.Data1, 4);
			m_pFile->Read(&guid.Data2, 2);
			m_pFile->Read(&guid.Data3, 2);
			m_pFile->Read(guid.Data4, 8);
			m_pHeader->SetProjectID(guid);

			m_pFile->Read(&n1, 1);
			m_pHeader->SetVersionMajor(n1);
			m_pFile->Read(&n1, 1);
			m_pHeader->SetVersionMinor(n1);

			m_pFile->Read(buf, 32);
			m_pHeader->SetSystemID(buf);
			m_pFile->Read(buf, 32);
			m_pHeader->SetSoftwareID(buf);
			m_pFile->Read(&n2, 2);
			m_pHeader->SetCreateDOY(n2);
			m_pFile->Read(&n2, 2);
			m_pHeader->SetCreateYear(n2);
			m_pFile->Read(&n2, 2);
			m_pHeader->SetHeaderSize(n2);
			if (m_pHeader->GetVersionMinor()<4)//TODO:
			{
				m_pFile->Read(&n4, 4);
				m_pHeader->SetDataOffset(n4);
			}
			else
			{
				m_pFile->Read(&n8, 8);
				m_pHeader->SetDataOffset(n8);
			}
			m_pFile->Read(&n4, 4);
			m_pHeader->SetRecordCount(n4);
			m_pFile->Read(&n1, 1);
			m_pHeader->SetPointFormat(n1);
			m_pFile->Read(&n2, 2);
			assert(n2 == m_pHeader->GetPointRecordLength());
			if (m_pHeader->GetVersionMinor()<4)//TODO:
			{
				m_pFile->Read(&n4, 4);
				m_pHeader->SetPointRecordsCount(n4);
			}
			else
			{
				m_pFile->Read(&n8, 8);
				m_pHeader->SetPointRecordsCount(n8);
			}
			int nReturns = 0;
			if (m_pHeader->GetVersionMinor()<=2)
			{
				nReturns = 5;
			} 
			else if (m_pHeader->GetVersionMinor() == 3)
			{
				nReturns = 7;
			} 
			else
			{
				nReturns = 15;
			}
			for (int i = 0;i<nReturns;i++)
			{
				if (m_pHeader->GetVersionMinor()<4)
				{
					m_pFile->Read(&n4, 4);
					m_pHeader->SetPointRecordsByReturn(i, n4);
				}
				else
				{
					m_pFile->Read(&n8, 8);
					m_pHeader->SetPointRecordsByReturn(i, n8);
				}
			}
			m_pFile->Read(&x1, 8);
			m_pFile->Read(&y1, 8);
			m_pFile->Read(&z1, 8);
			m_pFile->Read(&x2, 8);
			m_pFile->Read(&y2, 8);
			m_pFile->Read(&z2, 8);
			m_pHeader->SetScale(x1, y1, z1);
			m_pHeader->SetOffset(x2, y2, z2);

			m_pFile->Read(&x1, 8);
			m_pFile->Read(&x2, 8);
			m_pFile->Read(&y1, 8);
			m_pFile->Read(&y2, 8);
			m_pFile->Read(&z1, 8);
			m_pFile->Read(&z2, 8);
			m_pHeader->SetMax(x1, y1, z1);
			m_pHeader->SetMin(x2, y2, z2);

			if(m_pHeader->GetVersionMinor()>=3)
			{
				m_pFile->Read(&n8, 8);
				m_pHeader->SetStartOfWaveform(n8);
			}
		}

		Header* HeaderReader::GetHeader()
		{
			return m_pHeader;
		}

	}
